#ifndef IOSTREAM_TRANSFER_POLICY
#define IOSTREAM_TRANSFER_POLICY

#include<type_traits>
#include"..\..\meta_invoke\meta_invoke.hpp"

namespace meta_ios {
    namespace io_stream_transform_details {
        namespace transfer_protocols {
            namespace details {
                template<class meta_function_type>
                struct this_policy_type {
                    template<class this_type, class from_ins>
                    using apply = meta_invoke<meta_function_type, this_type>;
                };

                template<class meta_function_type>
                struct arg_policy_type {
                    template<class this_type, class from_ins>
                    using apply = meta_invoke<meta_function_type, from_ins>;
                };

                template<class meta_function_type>
                struct stream_to_policy_type {
                    template<class this_stream_t, class from_ins>
                    using apply = meta_invoke<meta_function_type, typename this_stream_t::to::type, from_ins>;
                };

                template<class meta_function_type>
                struct stream_to_arg_type {
                    template<class this_stream_t, class from_ins>
                    using apply = meta_invoke<meta_function_type, from_ins>;
                };

                template<class meta_function_type>
                struct stream_to_this_policy_type {
                    template<class this_stream_t, class from_ins>
                    using apply = meta_invoke<meta_function_type, typename this_stream_t::to::type>;
                };
                template<class meta_function_type> requires (meta_alias_argc<meta_function_type::template apply>() == 1)
                struct stream_to_this_policy_type<meta_function_type> {
                    template<class this_stream_t>
                    using apply = meta_invoke<meta_function_type, typename this_stream_t::to::type>;
                };

                template<class meta_function_type>
                struct stream_cache_policy_type {
                    template<class this_stream_t, class from_ins>
                    using apply = meta_invoke<meta_function_type, typename this_stream_t::cache, from_ins>;
                };

                template<class meta_function_type>
                struct stream_from_only_policy_type {
                    template<class this_stream_t>
                    using apply = meta_invoke<meta_function_type, typename this_stream_t::from::type>;
                };

                template<class meta_function_type>
                struct stream_cache_this_policy_type {
                    template<class this_stream_t>
                    using apply = meta_invoke<meta_function_type, typename this_stream_t::cache>;
                };

            }
        }
    }
}
#endif // !IOSTREAM_TRANSFER_POLICY
